package com.thinkgem.jeesite.modules.quartz.service;

import java.util.List;

import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.TriggerBuilder;
import org.quartz.TriggerKey;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.thinkgem.jeesite.common.persistence.Page;
import com.thinkgem.jeesite.common.service.CrudService;
import com.thinkgem.jeesite.modules.quartz.dao.SchedulejobDao;
import com.thinkgem.jeesite.modules.quartz.entity.Schedulejob;
import com.thinkgem.jeesite.modules.quartz.utils.QuartzJobFactory;
import com.thinkgem.jeesite.modules.quartz.utils.QuartzJobFactoryDisallowConcurrentExecution;



/**
 * 任务调度模块Service
 * @author zhangwei
 * @version 2015-05-20
 */
@Service
@Transactional(readOnly=false)
public class SchedulejobService extends CrudService<SchedulejobDao, Schedulejob> {
	
	@Autowired
	private SchedulerFactoryBean schedulerFactoryBean;
	
	public Schedulejob get(String id) {
		return super.get(id);
	}
	
	public List<Schedulejob> findList(Schedulejob schedulejob) {
		return super.findList(schedulejob);
	}
	
	public Page<Schedulejob> findPage(Page<Schedulejob> page, Schedulejob schedulejob) {
		return super.findPage(page, schedulejob);
	}
	
	@Transactional(readOnly = false)
	public void save(Schedulejob schedulejob) {
		super.save(schedulejob);
	}
	
	@Transactional(readOnly = false)
	public void delete(Schedulejob quaSchedulejob) {
		super.delete(quaSchedulejob);
	}
	
	public void testMethod(){
		for(int i=0;i<10;i++){
			System.out.println(i);
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
	/**
	 * 通过接口JobListener调用此方法，用于重新开始状态为1的任务
	 * @throws Exception
	 */
	public void init() throws Exception {
		List<Schedulejob> jobList = super.findList(new Schedulejob());
		for (Schedulejob job : jobList) {
			addJob(job);
			this.save(job);
		}
	}
	
	@Transactional(readOnly = false)	
	public void changeStatus(String id, String cmd) throws SchedulerException {
		Schedulejob job = dao.get(id);
		if (job == null) return;
		if (cmd.indexOf("stop")>-1) {
			deleteJob(job);
			job.setJobStatus(Schedulejob.STATUS_NOT_RUNNING);
		} else if (cmd.indexOf("start")>-1) {
			job.setJobStatus(Schedulejob.STATUS_RUNNING);
			addJob(job);
		} else if (cmd.indexOf("pause")>-1) {
			pauseJob(job);
			job.setJobStatus(Schedulejob.STATUS_PAUSE);
		} else if (cmd.indexOf("resume")>-1) {
			this.resumeJob(job);
			job.setJobStatus(Schedulejob.STATUS_RUNNING);
		}
		this.save(job);
	}
	
	
	public void addJob(Schedulejob job) throws SchedulerException {
		if (job == null || !Schedulejob.STATUS_RUNNING.equals(job.getJobStatus())) {
			return;
		}
		Scheduler scheduler = schedulerFactoryBean.getScheduler();
		TriggerKey triggerKey = TriggerKey.triggerKey(job.getJobName(), job.getJobGroup());
		CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
		// 不存在，创建一个
		if (null == trigger) {
 			Class clazz = "1".equals(job.getIsConcurrent()) ? QuartzJobFactory.class : QuartzJobFactoryDisallowConcurrentExecution.class;
			JobDetail jobDetail = JobBuilder.newJob(clazz).withIdentity(job.getJobName(), job.getJobGroup()).build();
			jobDetail.getJobDataMap().put("scheduleJob", job);
			CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression());
			trigger = TriggerBuilder.newTrigger().withIdentity(job.getJobName(), job.getJobGroup()).withSchedule(scheduleBuilder).build();
			scheduler.scheduleJob(jobDetail, trigger);
			job.setCreateDate(trigger.getStartTime());
		} else {
			// Trigger已存在，那么更新相应的定时设置
			CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression());
			// 按新的cronExpression表达式重新构建trigger
			trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();
			// 按新的trigger重新设置job执行
			scheduler.rescheduleJob(triggerKey, trigger);
		}
	}
	/**
	 * 暂停一个job
	 * 
	 * @param scheduleJob
	 * @throws SchedulerException
	 */
	public void pauseJob(Schedulejob scheduleJob) throws SchedulerException {
		Scheduler scheduler = schedulerFactoryBean.getScheduler();
		JobKey jobKey = JobKey.jobKey(scheduleJob.getJobName(), scheduleJob.getJobGroup());
		scheduler.pauseJob(jobKey);
	}

	/**
	 * 恢复一个job
	 * 
	 * @param scheduleJob
	 * @throws SchedulerException
	 */
	public void resumeJob(Schedulejob scheduleJob) throws SchedulerException {
		Scheduler scheduler = schedulerFactoryBean.getScheduler();
		JobKey jobKey = JobKey.jobKey(scheduleJob.getJobName(), scheduleJob.getJobGroup());
		scheduler.resumeJob(jobKey);
	}

	/**
	 * 删除一个job
	 * 
	 * @param scheduleJob
	 * @throws SchedulerException
	 */
	public void deleteJob(Schedulejob scheduleJob) throws SchedulerException {
		Scheduler scheduler = schedulerFactoryBean.getScheduler();
		JobKey jobKey = JobKey.jobKey(scheduleJob.getJobName(), scheduleJob.getJobGroup());
		scheduler.deleteJob(jobKey);
		scheduleJob.setCreateDate(null);
	}

	/**
	 * 立即执行job
	 * 
	 * @param scheduleJob
	 * @throws SchedulerException
	 */
	public void runAJobNow(Schedulejob scheduleJob) throws SchedulerException {
		Scheduler scheduler = schedulerFactoryBean.getScheduler();
		JobKey jobKey = JobKey.jobKey(scheduleJob.getJobName(), scheduleJob.getJobGroup());
		scheduler.triggerJob(jobKey);
	}
	
	/**
	 * 更改任务 cron表达式
	 * 
	 * @throws SchedulerException
	 */
	@Transactional(readOnly = false)
	public void updateCron(String id, String cron) throws SchedulerException {
		Schedulejob job = dao.get(id);
		if (job == null)  return;
		job.setCronExpression(cron);
		if (Schedulejob.STATUS_RUNNING.equals(job.getJobStatus())) {
			updateJobCron(job);
		}
		this.save(job);
	}
	/**
	 * 更新job时间表达式
	 * 
	 * @param scheduleJob
	 * @throws SchedulerException
	 */
	public void updateJobCron(Schedulejob scheduleJob) throws SchedulerException {
		Scheduler scheduler = schedulerFactoryBean.getScheduler();
		TriggerKey triggerKey = TriggerKey.triggerKey(scheduleJob.getJobName(), scheduleJob.getJobGroup());
		CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
		CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(scheduleJob.getCronExpression());
		trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();
		scheduler.rescheduleJob(triggerKey, trigger);
	}
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
}